#include "config.h"

#ifdef PLATFORM_WIN
#include "win_socket.h"
#else
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#endif

#include <stdlib.h>
#include <time.h>
#include "aux_types.h"
#include "aux_errno.h"
#include "aux_socket.h"
#include "aux_debugmsg.h"
#include "aux_time.h"


static TxIPCSocketInterface s_socket_inf = {NULL};

EErrNo xIPCCommonChkSocketAction(TxIPCSocket *ptSocket, ExIPCSocketAction eAct)
{
    if (!ptSocket)
        return -ERRNO_EPARAMETER_INVALID;

    switch (xIPCGetSocketState(ptSocket, SOCKET_STATE_INDEX_CUR))
    {
        case SOCKET_STATE_UNINITIALIZED:
            if (SOCKET_ACTION_INIT != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_INITIALIZED:
            if (SOCKET_ACTION_CREAT != eAct && SOCKET_ACTION_DEINIT != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_INITIALIZE_FAIL:
            if (SOCKET_ACTION_INIT != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_CREATED:
            if (SOCKET_TYPE_SERVER == ptSocket->eType &&
                SOCKET_ACTION_SERVER_BIND != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            if (SOCKET_TYPE_CLIENT == ptSocket->eType &&
                SOCKET_ACTION_CLIENT_CONNECT != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_CREATE_FAIL:
            if (SOCKET_ACTION_CREAT != eAct && SOCKET_ACTION_DEINIT != eAct)
                return -ERRNO_EWRONG;

            break;


        case SOCKET_STATE_CLIENT_CONNECT:
            if (SOCKET_TYPE_CLIENT != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_SEND != eAct && SOCKET_ACTION_RECV != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_CLIENT_CONNECT_FAIL:
            if (SOCKET_TYPE_CLIENT != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_CLIENT_CONNECT != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_SERVER_BIND:
            if (SOCKET_TYPE_SERVER != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_SERVER_LISTEN != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_SERVER_BIND_FAIL:
            if (SOCKET_TYPE_SERVER != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_SERVER_BIND != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_SERVER_LISTEN:
            if (SOCKET_TYPE_SERVER != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_SERVER_ACCEPT != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_SERVER_LISTEN_FAIL:
            if (SOCKET_TYPE_SERVER != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_SERVER_LISTEN != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_SERVER_ACCEPT:
            if (SOCKET_TYPE_SERVER != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_SERVER_LISTEN != eAct &&
                SOCKET_ACTION_SERVER_ACCEPT != eAct &&
                SOCKET_ACTION_SEND != eAct &&
                SOCKET_ACTION_RECV != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_SERVER_ACCEPT_FAIL:
            if (SOCKET_TYPE_SERVER != ptSocket->eType)
                return -ERRNO_EWRONG;

            if (SOCKET_ACTION_SERVER_ACCEPT != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_SEND:
        case SOCKET_STATE_SEND_FAIL:
        case SOCKET_STATE_RECV:
        case SOCKET_STATE_RECV_FAIL:
            if (SOCKET_TYPE_SERVER == ptSocket->eType)
            {
                if (SOCKET_ACTION_SERVER_LISTEN != eAct &&
                    SOCKET_ACTION_SEND != eAct &&
                    SOCKET_ACTION_RECV != eAct &&
                    SOCKET_ACTION_CLOSE != eAct)
                    return -ERRNO_EWRONG;
            }
            else if (SOCKET_TYPE_CLIENT == ptSocket->eType ||
                    SOCKET_TYPE_REMOTE_CLIENT == ptSocket->eType)
            {
                if (SOCKET_ACTION_SEND != eAct &&
                    SOCKET_ACTION_RECV != eAct &&
                    SOCKET_ACTION_CLOSE != eAct)
                    return -ERRNO_EWRONG;
            }
            else
            {
                return -ERRNO_EPARAMETER_INVALID;
            }

            break;

        case SOCKET_STATE_CLOSE:
            if (SOCKET_ACTION_DEINIT != eAct &&
                SOCKET_ACTION_CREAT != eAct &&
                SOCKET_ACTION_CLOSE != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_CLOSE_FAIL:
            if (SOCKET_STATE_CLOSE_FAIL == // forbide the dead loop
                    xIPCGetSocketState(ptSocket, SOCKET_STATE_INDEX_PREV_1))
                return -ERRNO_EWRONG;
			xIPCPopSocketState(ptSocket, NULL);
            return xIPCCommonChkSocketAction(ptSocket, eAct);

            break;

        case SOCKET_STATE_DEINITIALIZED:
            if (SOCKET_ACTION_INIT != eAct)
                return -ERRNO_EWRONG;

            break;

        case SOCKET_STATE_DEINITIALIZE_FAIL:
            if (SOCKET_ACTION_CREAT != eAct && SOCKET_ACTION_DEINIT != eAct)
                return -ERRNO_EWRONG;

            break;

        default:
            return -ERRNO_EWRONG;
    }

    return ERRNO_SUCCESS;
}

ExIPCSocketState xIPCGetSocketState(TxIPCSocket *pSocket,
                                            ExIPCSocketStateIndex nIndex)
{
    if (!pSocket || nIndex >= SOCKET_STATE_INDEX_MAX)
        return SOCKET_STATE_INVALID;

    return pSocket->eSocketStat[nIndex];
}

EErrNo xIPCSetSocketState(TxIPCSocket *pSocket, ExIPCSocketStateIndex nIndex,
                        ExIPCSocketState eState)
{
    if (!pSocket || nIndex >= SOCKET_STATE_INDEX_MAX)
        return -ERRNO_EPARAMETER_INVALID;

    pSocket->eSocketStat[nIndex] = eState;
    return ERRNO_SUCCESS;
}

EErrNo xIPCPushSocketState(TxIPCSocket *pSocket, ExIPCSocketState eState)
{
	if (!pSocket)
		return -ERRNO_EPARAMETER_INVALID;

	pSocket->eSocketStat[SOCKET_STATE_INDEX_PREV_2] =
		pSocket->eSocketStat[SOCKET_STATE_INDEX_PREV_1];
	pSocket->eSocketStat[SOCKET_STATE_INDEX_PREV_1] =
		pSocket->eSocketStat[SOCKET_STATE_INDEX_CUR];
	pSocket->eSocketStat[SOCKET_STATE_INDEX_CUR] = eState;
	return ERRNO_SUCCESS;
}

EErrNo xIPCPopSocketState(TxIPCSocket *pSocket, ExIPCSocketState *eState)
{
	if (!pSocket)
		return -ERRNO_EPARAMETER_INVALID;

	if (eState)
		*eState = pSocket->eSocketStat[SOCKET_STATE_INDEX_CUR];
	pSocket->eSocketStat[SOCKET_STATE_INDEX_CUR] =
		pSocket->eSocketStat[SOCKET_STATE_INDEX_PREV_1];
	pSocket->eSocketStat[SOCKET_STATE_INDEX_PREV_1] =
		pSocket->eSocketStat[SOCKET_STATE_INDEX_PREV_2];
	return ERRNO_SUCCESS;
}

EErrNo xIPCGetSocketInterface(TxIPCSocketInterface *ptInterface)
{
    EErrNo eRet = ERRNO_FAIL;
    if (!ptInterface)
    {
        aux_prt_err("xIPCGetSocketInterface parameter NULL\n");
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (ERRNO_TRUE == ptInterface->eLoad)
        return ERRNO_SUCCESS;

#ifdef PLATFORM_WIN
    eRet = aux_get_win32_socket_intf(ptInterface);
#else
#ifdef PLATFORM_LINUX
    eRet = xIPCLinuxSocketInterface(ptInterface);
#endif
#endif
    if (ERRNO_SUCCESS == eRet)
        ptInterface->eLoad = ERRNO_TRUE;
    else
        ptInterface->eLoad = ERRNO_FALSE;

    return eRet;
}

EErrNo xIPCInitSocket(TxIPCSocket *ptSocket, s32 nSendTimeout,
                            s32 nRecvTimeout)
{
    if (!ptSocket)
    {
        aux_prt_err("xIPCInitSocket parameter NULL\n");
        return -ERRNO_EPARAMETER_INVALID;
    }
    memset(ptSocket, 0, sizeof(TxIPCSocket));

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCInitSocket xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (s_socket_inf.Init && ERRNO_SUCCESS != s_socket_inf.Init(ptSocket))
    {
        aux_prt_err("xIPCInitSocket Init fail\n");
        return -FERR(2);
    }

    if (s_socket_inf.Create && ERRNO_SUCCESS != s_socket_inf.Create(
                                        ptSocket, nSendTimeout, nRecvTimeout))
    {
        aux_prt_err("xIPCInitSocket Create fail\n");
        return -FERR(3);
    }

    return ERRNO_SUCCESS;
}

EErrNo xIPCDeinitSocket(TxIPCSocket* pSocket)
{
    if (!pSocket)
    {
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCSocketServerExit xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (s_socket_inf.Close && ERRNO_SUCCESS != s_socket_inf.Close(pSocket))
    {
        aux_prt_err("xIPCSocketServerExit Close fail\n");
        return -FERR(2);
    }

    if (s_socket_inf.Deinit && ERRNO_SUCCESS != s_socket_inf.Deinit(pSocket))
    {
        aux_prt_err("xIPCSocketServerExit Deinit fail\n");
        return -FERR(3);
    }

    return ERRNO_SUCCESS;
}

////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////SERVER////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////

static EErrNo xIPCSocketServerStart(TxIPCSocket* pSocket,
                                            char *pszIp, u16 wPort,
                                            s32 nSendTimeout, s32 nRecvTimeout)
{
    if (!pSocket)
        return -ERRNO_EPARAMETER_INVALID;

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCSocketServerStart xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (ERRNO_SUCCESS != xIPCInitSocket(pSocket, nSendTimeout, nRecvTimeout))
    {
        aux_prt_err("xIPCSocketServerStart xIPCGetLocalSocket fail\n");
        return -FERR(2);
    }

    if (!pszIp)
        strcpy(pSocket->szIpStr, LOCAL_IP_STR);
    else
        strcpy(pSocket->szIpStr, pszIp);

    pSocket->wPort = wPort;
    pSocket->eType = SOCKET_TYPE_SERVER;

    if (s_socket_inf.Bind && ERRNO_SUCCESS != s_socket_inf.Bind(pSocket))
    {
        aux_prt_err("xIPCSocketServerStart Bind fail\n");
        return -FERR(3);
    }

    if (s_socket_inf.Listen && ERRNO_SUCCESS != s_socket_inf.Listen(pSocket))
    {
        aux_prt_err("xIPCSocketServerStart Listen fail\n");
        return -FERR(4);
    }

    return ERRNO_SUCCESS;
}

static EErrNo xIPCSocketServerWaitForClient(TxIPCSocket* pLocal,
                                                       TxIPCSocket *pRemote)
{
#define __FUNCTION_NAME__ "xIPCSocketServerWaitForClient"
    EErrNo eRet;

    if (!pLocal || !pRemote)
    {
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        AUX_DEBUG_STR("xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    /* Accept MUST NOT NULL */
    if (NULL == s_socket_inf.Accept )
    {
        AUX_DEBUG_STR("Accept NULL\n");
        return -FERR(2);
    }
    eRet = s_socket_inf.Accept(pLocal, pRemote);


    return eRet;
#undef __FUNCTION_NAME__
}

static EErrNo xIPCSocketServerSend(TxIPCSocket* pLocal, TxIPCSocket *pRemote,
                                    u8 *pabyData, s32 *pnSize)
{
#define __FUNCTION_NAME__ "xIPCSocketServerSend"

    s32 nDataByteLeft = 0;
    s32 nActualSend   = 0;
    EErrNo eRet;

    if (!pLocal || !pRemote || (!pabyData && (*pnSize > 0)))
    {
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (*pnSize <= 0)
    {
        return ERRNO_SUCCESS;
    }

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        AUX_DEBUG_STR("xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (NULL == s_socket_inf.Send)
    {
        AUX_DEBUG_STR("Send NULL\n");
        return -FERR(2);
    }

    nDataByteLeft = *pnSize;
    nActualSend   = nDataByteLeft;
    /* Send MUST NOT NULL */
    do {
        eRet = s_socket_inf.Send(pRemote, pabyData, &nActualSend);
        nDataByteLeft -= nActualSend;
        pabyData      += nActualSend;

        nActualSend    = nDataByteLeft;
    } while (nDataByteLeft > 0 && ERRNO_SUCCESS == eRet);

    *pnSize -= nDataByteLeft;

    if (ERRNO_REMOTE_CLOSED == eRet)
    {
        AUX_DEBUG_STR("client close socket\n");
        return ERRNO_REMOTE_CLOSED;
    }

    if (nDataByteLeft <= 0)
    {
        //AUX_DEBUG_STR("send ok\n");
        return ERRNO_SUCCESS;
    }
    else
    {
        AUX_DEBUG_STR("send fail\n");
        return ERRNO_FAIL;
    }
#undef __FUNCTION_NAME__

}

static EErrNo xIPCSocketServerRecv(TxIPCSocket* pLocal, TxIPCSocket *pRemote,
                                           u8 *pabyData, s32 *pnSize)
{
    EErrNo eRet;

    if (!pLocal || !pRemote || (!pabyData && (*pnSize > 0)))
    {
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (*pnSize <= 0)
    {
        return ERRNO_SUCCESS;
    }

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCSocketServerRecv xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (NULL == s_socket_inf.Recv)
    {
        aux_prt_err("xIPCSocketServerRecv Recv NULL\n");
        return -FERR(2);
    }

    /* Recv MUST NOT NULL */
    eRet = s_socket_inf.Recv(pRemote, pabyData, pnSize);
    if(ERRNO_REMOTE_CLOSED == eRet)
    {
        *pnSize = 0;
        return ERRNO_REMOTE_CLOSED;
    }
    else if (ERRNO_TIMEOUT == eRet)
    {
        *pnSize = 0;
        return ERRNO_TIMEOUT;
    }

    if (ERRNO_SUCCESS != eRet)
    {
        *pnSize = 0;
        aux_prt_err("xIPCSocketServerRecv Recv fail\n");
        return ERRNO_FAIL;
    }
    else
    {
        //if (*pnSize > 0)
        //    aux_prt_err("recv %d bytes\n", *pnSize);
        return ERRNO_SUCCESS;
    }
}

static EErrNo xIPCSocketServerCloseClient(TxIPCSocket* pLocal,
                                                     TxIPCSocket *pRemote)
{
    if (!pLocal || !pRemote)
    {
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCSocketServerCloseClient xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (NULL == s_socket_inf.Close)
    {
        aux_prt_err("xIPCSocketServerCloseClient Close NULL\n");
        return -FERR(2);
    }

    if(ERRNO_SUCCESS != s_socket_inf.Close(pRemote))
    {
        return ERRNO_FAIL;
    }

    return ERRNO_SUCCESS;

}




static EErrNo xIPCSocketServerExit(TxIPCSocket* pLocal)
{
    return xIPCDeinitSocket(pLocal);
}



////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////CLIENT////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
static EErrNo xIPCSocketClientStart(TxIPCSocket* pSocket,
                                     const char *pszServerIp, u16 wPort,
                                     s32 nSendTimeout, s32 nRecvTimeout)
{
    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCSocketClientStart xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (ERRNO_SUCCESS != xIPCInitSocket(pSocket, nSendTimeout, nRecvTimeout))
    {
        aux_prt_err("xIPCSocketClientStart xIPCGetLocalSocket fail\n");
        return -FERR(2);
    }

    strcpy(pSocket->szIpStr, pszServerIp);
    pSocket->wPort = wPort;
    pSocket->eType = SOCKET_TYPE_CLIENT;

    if (s_socket_inf.Connect && ERRNO_SUCCESS != s_socket_inf.Connect(pSocket))
    {
        aux_prt_err("xIPCSocketClientStart Connect fail\n");
        return -FERR(3);
    }

    return ERRNO_SUCCESS;
}

/* send don't need timeout */
static EErrNo xIPCSocketClientSend(TxIPCSocket *pSocket,
                                           u8 *pabyData, s32 *pnSize)
{
#define __FUNCTION_NAME__ "xIPCSocketClientSend"
    s32 nDataByteLeft = 0;
    s32 nActualSend   = 0;
    EErrNo eRet;

    if (!pSocket || (!pabyData && (*pnSize > 0)))
    {
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (*pnSize <= 0)
    {
        return ERRNO_SUCCESS;
    }

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        AUX_DEBUG_STR("xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (NULL == s_socket_inf.Send)
    {
        AUX_DEBUG_STR("Send NULL\n");
        return -FERR(2);
    }

    nDataByteLeft = *pnSize;
    nActualSend   = nDataByteLeft;
    /* Send MUST NOT NULL */
    /* this method not work ok all the time, to fix future */
    do {
        eRet = s_socket_inf.Send(pSocket, pabyData, &nActualSend);
        nDataByteLeft -= nActualSend;
        pabyData      += nActualSend;

        nActualSend    = nDataByteLeft;

        //srand(time(0));

        //aux_sleep_ms(rand() % 50); /* sleep <=50 ms */
    } while (nDataByteLeft > 0 && ERRNO_SUCCESS == eRet);

    *pnSize -= nDataByteLeft;

    if (ERRNO_REMOTE_CLOSED == eRet)
    {
        AUX_DEBUG_STR("router close socket\n");
        return ERRNO_REMOTE_CLOSED;
    }

    if (nDataByteLeft <= 0)
    {
        //AUX_DEBUG_STR("send ok\n");
        return ERRNO_SUCCESS;
    }
    else
    {
        AUX_DEBUG_STR("send fail\n");
        return ERRNO_FAIL;
    }
#undef __FUNCTION_NAME__
}

static EErrNo xIPCSocketClientRecv(TxIPCSocket *pSocket,
                                    u8 *pabyData, s32 *pnSize)
{
    EErrNo eRet;
    if (!pSocket || (!pabyData && (*pnSize > 0)))
    {
        return -ERRNO_EPARAMETER_INVALID;
    }

    if (*pnSize <= 0)
    {
        return ERRNO_SUCCESS;
    }

    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCSocketClientRecv xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (NULL == s_socket_inf.Recv)
    {
        aux_prt_err("xIPCSocketClientRecv Recv NULL\n");
        return -FERR(2);
    }

    /* Recv MUST NOT NULL */
    eRet = s_socket_inf.Recv(pSocket, pabyData, pnSize);
    if (ERRNO_REMOTE_CLOSED == eRet)
    {
        *pnSize = 0;
        return ERRNO_REMOTE_CLOSED;
    }

    if (ERRNO_TIMEOUT == eRet)
    {
        *pnSize = 0;
        return ERRNO_TIMEOUT;
    }

    if(ERRNO_SUCCESS != eRet)
    {
        aux_prt_err("xIPCSocketClientRecv Recv fail\n");
        *pnSize = 0;
        return ERRNO_FAIL;
    }
    else
    {
        return ERRNO_SUCCESS;
    }
}

static EErrNo xIPCSocketClientExit(TxIPCSocket* pSocket)
{
    return xIPCDeinitSocket(pSocket);
}


///////////////////////////////////////////////////////////////////////////////

EErrNo xIPCComponentSocketInit()
{
    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCComponentSocketInit xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (s_socket_inf.PlatformInit &&
        ERRNO_SUCCESS != s_socket_inf.PlatformInit())
    {
        aux_prt_err("xIPCComponentSocketInit PlatformInit fail\n");
        return -FERR(2);
    }

    return ERRNO_SUCCESS;
}

EErrNo xIPCComponentSocketDeinit()
{
    if (ERRNO_SUCCESS != xIPCGetSocketInterface(&s_socket_inf))
    {
        aux_prt_err("xIPCComponentSocketDeinit xIPCGetSocketInterface fail\n");
        return -FERR(1);
    }

    if (s_socket_inf.PlatformDeinit &&
        ERRNO_SUCCESS != s_socket_inf.PlatformDeinit())
    {
        aux_prt_err("xIPCComponentSocketDeinit PlatformDeinit fail\n");
        return -FERR(2);
    }

    return ERRNO_SUCCESS;
}

EErrNo xIPCComponentGetSocketServerInterface(TxIPCSocketServer *pServer)
{
    if (!pServer)
        return ERRNO_FAIL;

    memset(pServer, 0, sizeof(TxIPCSocketServer));
    pServer->Start       = xIPCSocketServerStart;
    pServer->WaitClient  = xIPCSocketServerWaitForClient;
    pServer->CloseClient = xIPCSocketServerCloseClient;
    pServer->Send        = xIPCSocketServerSend;
    pServer->Recv        = xIPCSocketServerRecv;
    pServer->Exit        = xIPCSocketServerExit;
    return ERRNO_SUCCESS;
}

EErrNo xIPCComponentPutSocketServerInterface(TxIPCSocketServer *pServer)
{
    return ERRNO_SUCCESS;
}


EErrNo xIPCComponentGetSocketClientInterface(TxIPCSocketClient *pClient)
{
    if (!pClient)
        return ERRNO_FAIL;

    memset(pClient, 0, sizeof(TxIPCSocketClient));
    pClient->Start = xIPCSocketClientStart;
    pClient->Send  = xIPCSocketClientSend;
    pClient->Recv  = xIPCSocketClientRecv;
    pClient->Exit  = xIPCSocketClientExit;

    return ERRNO_SUCCESS;
}

EErrNo xIPCComponentPutSocketClientInterface(TxIPCSocketClient *pClient)
{
    if (!pClient)
        return ERRNO_FAIL;

    memset(pClient, 0, sizeof(TxIPCSocketClient));

    return ERRNO_SUCCESS;
}


